﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;


namespace SessionFacade
{
    public class Wrapper
    {
        #region Members
        
#if Deprecated
        #region UserID

        /// <summary>
        /// Returns the userID as a Int32 instead of an object.
        /// </summary>
        public static Int32 iUserID
        {
            get
            {
                return (Int32)GetValueOrDefault(HttpContext.Current.Session.SessionID.ToString() + "_UserID", nUSERID_UNKOWN);
            }
            set
            {
                if (nUSERID_MINIMUM >= value)
                {
                    throw new ApplicationException(String.Format(sUSERID_INVALID, value, nUSERID_MINIMUM));
                }
                SetValue(eKeys.UserID, value);
            }
        }

        /// <summary>
        /// Return the userID as a string instead of an object.
        /// </summary>
        public static string sUserID
        {
            get
            {
                return (string)GetValueOrDefault(HttpContext.Current.Session.SessionID.ToString() + "_UserID", nUSERID_UNKOWN);
            }
            set
            {
                if (value.Length == 0)
                {
                    throw new Exception("UserID length must be greater than 0");
                }
                SetValue(HttpContext.Current.Session.SessionID.ToString() + "_UserID", value);
            }
        }
        
        #endregion
#endif

        /// <summary>
        /// Variable Groups
        /// </summary>
        static List<Group> Groups 
        { 
            get { return GetValueOrDefault<List<Group>>(HttpContext.Current.Session.SessionID.ToString() + "_Groups", new List<Group>()); }
            set { SetValue<List<Group>>(HttpContext.Current.Session.SessionID.ToString() + "_Group", value); }
        }

        /// <summary>
        /// Referenced Variables
        /// </summary>
        static List<Variable<object>> Variables
        {
            get { return GetValueOrDefault<List<Variable<object>>>(HttpContext.Current.Session.SessionID.ToString() + "_Groups", new List<Variable<object>>()); }
            set { SetValue<List<Variable<object>>>(HttpContext.Current.Session.SessionID.ToString() + "_Group", value); }
        }
       
        #endregion

        #region Methods

        /// <summary>
        /// Gets the session value from the specified key.
        /// </summary>
        /// <param name="sKey">The key to get the value from</param>
        /// <returns>The session value for the specified session key.
        /// If the key does not exist, null is returned.
        /// </returns>
        private static T GetValue<T>(string sKey)
        {
            return (T)HttpContext.Current.Items[sKey.ToString()];
        }

        /// <summary>
        /// Stores the specified session-value to the specified session-key.
        /// </summary>
        /// <param name="sKey">The key for the value to store in the session.</param>
        /// <param name="oValue">The value to store in the session</param>
        private static void SetValue<T>(string sKey, T oValue)
        {
            HttpContext.Current.Items[sKey] = oValue;
        }

        /// <summary>
        /// Gets the value from the session object.
        /// </summary>
        /// <param name="sKey"> The session key to get the value for.</param>
        /// <param name="oDefaultValue">The default value to use if no valid value stored.</param>
        /// <returns>When the value is null or the key does not exist, 
        /// the specified default value is returned. 
        /// Otherwise, the value is returned</returns>
        private static T GetValueOrDefault<T>(string sKey, T oDefaultValue)
        {
            T oValue = GetValue<T>(sKey);
            if (null == oValue)
            {
                return oDefaultValue;
            }
            return oValue;
        }

        /// <summary>
        /// Dispose the Variable by Group
        /// </summary>
        /// <param name="group"></param>
        public static void DisposeByGroup(Group group)
        {
            List<Variable<object>> GroupedVars = new List<Variable<object>>();
            foreach (Variable<object> var in Variables)
            {
                Group _group = var.Groups.Find(delegate(Group foundgroup) { return foundgroup.ID == group.ID; });
                if (_group != null)
                {
                    GroupedVars.Add(var);
                }

            }
            Variables.RemoveAll
            (
                delegate 
                    (
                        Variable<object> foundVar
                    ) 
                    {
                        return foundVar.Groups.Find
                            (
                                delegate
                                (
                                    Group foundgroup
                                )
                                {
                                    return foundgroup.ID == group.ID;
                                }
                             ).ID == group.ID;
                    }
             );
                    
        }

        /// <summary>
        /// Dispose of the Variable by it's name
        /// </summary>
        /// <param name="var"></param>
        public static void DisposeByName(Variable<object> var)
        {
            Variables.RemoveAll
            (
                delegate
                    (
                        Variable<object> foundVar
                    )
                {
                    return foundVar.Name == var.Name;
                }
             );
        }


        #endregion
    }
}
